package com.qf.service.impl;

import com.qf.config.IdWorker;
import com.qf.constant.CacheConstants;
import com.qf.constant.RabbitMQConstants;
import com.qf.constant.ReportStateConstants;
import com.qf.constant.SourceType;
import com.qf.controller.InterfaceController;
import com.qf.feign.CacheFeign;
import com.qf.form.SmsInterfaceForm;
import com.qf.model.StandardSubmit;
import com.qf.service.InterfaceService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * projectName: sms-platform02
 *
 * @author: 元
 * time: 2021/10/16 0016 9:57
 * description:
 */
@Service
@Slf4j
public class InterfaceServiceImpl implements InterfaceService {

    Logger logger = LoggerFactory.getLogger(InterfaceController.class);

    @Autowired
    private CacheFeign cacheFeign;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IdWorker idWorker;


    @Override
    public Map<String, String> checkInterFaceForm(SmsInterfaceForm smsInterfaceForm) {
        Map<String,String> resultMap = new HashMap<>();

        /**
         * 1.校验ClientId,根据redis中缓存数据,进行查找
         */
        String clientID = smsInterfaceForm.getClientID();
            //再远程调用cache模块,从redis中获取短信对象
        Map clientObj = cacheFeign.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + clientID);

        if (clientObj == null || clientObj.size() == 0){
            logger.info("[接口模块] 认证错误,clientID={}",clientID);
            resultMap.put("code","101");
            resultMap.put("msg","认证错误,clientID错误");
            return resultMap;
        }

        /**
         * 2.校验pwd密码,根据redis中用户密码,进行校验
         */
        String pwd = smsInterfaceForm.getPwd();
        if (!pwd.equals(clientObj.get("pwd"))){
            logger.info("[接口模块] 密码错误,pwd={}",pwd);
            resultMap.put("code","102");
            resultMap.put("msg","密码错误");
            return resultMap;
        }
        /**
         * 3.校验IP,根据redis中预留的用户IP进行校验
         */
        String ip = smsInterfaceForm.getIp();
        //从redis中获取服务器IP地址集合
        String ipaddress = (String)clientObj.get("ipaddress");
        String [] ipArray = ipaddress.split(",");
        //ip地址是否校验成功
        boolean flag = false;
        //遍历IP地址集合
        if (ipArray != null){
            for (String realIP: ipArray){
                if (ip.equals(realIP)){
                    //若IP地址正确
                    flag = true;
                    break;
                }
            }
        }
        //判断flag,如果IP地址不正确返回异常提示
        if (!flag){
            logger.info("[接口模块] IP地址错误,ip={}",ip);
            resultMap.put("code","103");
            resultMap.put("msg","IP地址错误");
            return resultMap;
        }

        /**
         * 4.校验手机号
         * */
        String mobile = smsInterfaceForm.getMobile();
        String [] mobileArray = mobile.split(",");
        //校验手机号位数
        if (mobileArray.length == 0 || mobileArray.length>100){
            logger.info("[接口模块] 手机号错误,mobile={}",mobile);
            resultMap.put("code","105");
            resultMap.put("msg","手机号错误");
            return resultMap;
        }
        //正则表达式校验手机号码
        Set<String> errorMobile = new HashSet<>();
        String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$";
        for (String phone : mobileArray){
            if (!phone.matches(regex)){
                //将有问题的手机号放入错误手机号集合中
                errorMobile.add(phone);
            }
        }
        //再判断错误手机号集合中是否有错误的手机号码字符串
        if (errorMobile.size()>0){
            logger.info("[接口模块] 手机号错误,mobile={}",mobile);
            resultMap.put("code","105");
            resultMap.put("msg","手机号错误");
            return resultMap;
        }

        /***
         * 5.校验下行编码,需要非空,且为数字格式
         */
        String srcIDStr = smsInterfaceForm.getSrcID();
        Long srcID= null;
        try {
            srcID = Long.parseLong(srcIDStr);
        }catch (NumberFormatException e){
            logger.info("[接口模块] 下行编码错误,srcID={}",srcID);
            resultMap.put("code","106");
            resultMap.put("msg","下行编码错误");
            return resultMap;
        }
    /***
    *6.如果以上校验均成功,则封装短信对象,将数据发生到MQ中
     */
    //根据手机号封装短信平台内部的短信对象
    for(String phone : mobileArray){
        StandardSubmit standardSubmit = new StandardSubmit();
        //该对象的唯一ID
        standardSubmit.setSequenceId(String.valueOf(idWorker.nextId()));
        //获取客户端ID
        standardSubmit.setClientID(Integer.parseInt(smsInterfaceForm.getClientID()));
        //发送时间
        standardSubmit.setSendTime(new Date());
        //发送目标手机号
        standardSubmit.setDestMobile(phone);
        //发生内容
        standardSubmit.setMessageContent(smsInterfaceForm.getContent());
        //消息的优先级,0最低,3最高
        standardSubmit.setMessagePriority(Short.parseShort(String.valueOf(clientObj.get("priority"))));
        //设置短信发生方式,一般是HTTP
        standardSubmit.setSource(SourceType.HTTP);
        //客户端唯一序列号,即下行编码
        standardSubmit.setSrcSequenceId(srcID);
        standardSubmit.setReportState(ReportStateConstants.WAIT);

        rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND +"_exchange","routingKey",standardSubmit);

    }

        resultMap.put("code","0");
        resultMap.put("msg","接收成功");
        return resultMap;
    }
}
